// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.XPath;
using System.Globalization;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Wit
{
    /// <summary>
    /// Represents mapping between Tfs and Other system values.
    /// </summary>
    public sealed class ValueMap
    {
        private string m_name;                              //Name of the value map
        private Dictionary<string, string> m_tfsToOther;    //Tfs to Other mapping
        private Dictionary<string, string> m_otherToTfs;    //Other to Tfs mapping

        /// <summary>
        /// Name of the value map.
        /// </summary>
        public string Name { get { return m_name; } }

        /// <summary>
        /// Mapping of Tfs values to values in the other system.  Tfs values are the key.
        /// </summary>
        public Dictionary<string, string> TfsToOther { get { return m_tfsToOther; } }

        /// <summary>
        /// Mapping of values in the other system to Tfs values.  Other system values are the key.
        /// </summary>
        public Dictionary<string, string> OtherToTfs { get { return m_otherToTfs; } }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="nav">XPath navigator positioned to a ValueMap node.</param>
        internal ValueMap(XPathNavigator nav)
        {
            m_tfsToOther = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            m_otherToTfs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            
            m_name = nav.GetAttribute("name", string.Empty);

            XPathNodeIterator set = nav.SelectChildren(XPathNodeType.Element);
            foreach (XPathNavigator item in set)
            {
                string tfs = item.GetAttribute("tfs", string.Empty);
                string other = item.GetAttribute("other", string.Empty);

                m_tfsToOther.Add(tfs, other);
                m_otherToTfs.Add(other, tfs);
            }
        }

        /// <summary>
        /// Maps a value on one side to its value on the other side.
        /// If the input value is not found, then in the input value is returned.
        /// </summary>
        /// <param name="input">Value on the source side</param>
        /// <param name="sourceSystemType">System type for the source side</param>
        /// <returns>The mapped value; or the input value, if the input was not found in the map.</returns>
        public object GetValue(object input, SystemType sourceSystemType)
        {
            string inputStr = Convert.ToString(input, CultureInfo.InvariantCulture);
            string outputStr = inputStr;

            if (sourceSystemType == SystemType.Tfs)
            {
                if (!TfsToOther.TryGetValue(inputStr, out outputStr))
                {
                    outputStr = null;
                }
            }
            else
            {
                if(!OtherToTfs.TryGetValue(inputStr, out outputStr))
                {
                    outputStr = null;
                }
            }

            return (outputStr == null)? inputStr : outputStr;
        }
    }
}
